package com.ruoyi.file.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import java.io.*;
import java.security.Key;
import java.util.Random;

/**
 * 1) 加密算法：AES
 * 2) 加密模式：CBC
 * 3) 填充方式：PKCS5Padding/NoPadding
 */
public class FileEnAES {

    public static void Encryption (String str1,String s,String s2) throws Exception {
        //str1 为密钥文件地址 ,str2 为待加密数据,s2为用于存储加密后数据的文件

        FileInputStream f1=new FileInputStream (str1);
        ObjectInputStream b=new ObjectInputStream(f1);
        Key k=(Key)  b.readObject ();								//获取密钥
        //生成初始化向量
        byte[] rand=new byte [16] ;
        Random r=new Random ( ) ;
        r.nextBytes (rand) ;
        IvParameterSpec iv=new IvParameterSpec (rand) ;				//加密
        Cipher cp= Cipher.getInstance ("AES /CBC/PKCS5Padding" ) ;
        cp.init (Cipher.ENCRYPT_MODE,k, iv) ;
        byte ptext [ ]=s.getBytes ("UTF8");
        byte ctext [ ]=cp.doFinal (ptext) ;							//打印加密结果
        System.out.println("加密结果为:");
        for(int i=0;i<ctext.length;i++){
            System.out.print (ctext [i] +" ");
        }
        //保存加密结果
        FileOutputStream f2=new FileOutputStream ( s2) ;
        f2.write (rand) ;
        f2.write(ctext);
    }
    public static void Decryption (String str1,String str2,String str3) throws Exception {
        //str1 为密钥文件地址 ,str2为待解密的文件,str3为用于存储解密后数据的文件
        //获取初始向量
        FileInputStream f=new FileInputStream ( str2) ;
        byte [] rand2=new byte[16] ;
        f.read (rand2) ;
        IvParameterSpec iv2=new IvParameterSpec (rand2) ;			//获取密文
        int num=f.available ( );
        byte[ ] ctext2=new byte [num] ;
        f.read (ctext2);
        //获取密钥
        FileInputStream f3=new FileInputStream ( str1 ) ;
        ObjectInputStream b2=new ObjectInputStream(f3);
        Key k2=(Key ) b2.readObject ( ) ;
        //获取密码器，执行解密
        Cipher cp2=Cipher.getInstance ("AES /CBC/ PKCS5Padding" ) ;
        cp2.init (Cipher.DECRYPT_MODE,k2, iv2) ;

        byte []ptext2=cp2.doFinal (ctext2 ) ;
        String p=new String(ptext2 ,"UTF8") ;
        System.out.println ("解密结果为：") ;
        System.out.println (p) ;									//输出解密结果

        FileOutputStream f2=new FileOutputStream ( str3) ;			//存储解密结果
//        f2.write (rand2) ;
        f2.write(Base64.decode(ptext2));
    }

    public static String Read (String str1)							//读取待加密文件
    {
        //String str1="C:/myjava/Hello.java";
        File file=new File(str1);
        //根据路径创建File类对象--这里路径即使错误也不会报错，因为只是产生File对象，还并未与计算机文件读写有关联
//        byte[] bytes=new byte[(int) file.length()];
        //根据文件的长度创建byte数组的长度
        try{
            FileInputStream fileInput=new FileInputStream(file);
            //与根据File类对象的所代表的实际文件建立链接创建fileInputStream对象
            try {
//                int data = fileInput.read(bytes,0,(int) file.length()) ;
//                String str=new String(bytes,0,data);
                String encode = Base64.encode(fileInput);
                return encode;
                //System.out.println(str);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e)
        {
            e.printStackTrace();
            System.out.println("文件不存在或者文件不可读或者文件是目录");
        }
        return null;

    }
}
